package core

import (
	"context"
	"log"
	"time"

	"github.com/coreos/etcd/client"
	"github.com/spf13/viper"
)

type EtcdV2 struct {
	Client client.Client
	Kv     client.KeysAPI
	Vp     *viper.Viper
	//Lease   client.
}

var (
	GEtcdV2 *EtcdV2
)

func InitEtcdV2(Vp *viper.Viper) (err error) {
	var (
		config client.Config
	)
	GEtcdV2 = &EtcdV2{Vp: Vp}
	config = client.Config{
		Endpoints:               Vp.GetStringSlice("etcd.endpoints"),
		Transport:               client.DefaultTransport,
		HeaderTimeoutPerRequest: time.Duration(Vp.GetInt("etcd.timeout")) * time.Millisecond,
	}
	if GEtcdV2.Client, err = client.New(config); err != nil {
		log.Println(err.Error())
		return
	}

	GEtcdV2.Kv = client.NewKeysAPI(GEtcdV2.Client)
	return err
}

func (E *EtcdV2) Get(ctx context.Context, path string) (data string, err error) {
	res, err := E.Kv.Get(ctx, path, &client.GetOptions{
		Recursive: true,
		Sort:      false,
		Quorum:    false,
	})
	if err != nil {
		return
	}
	data = res.Node.Value
	E.Vp.Set(path, data)
	return
}

func (E *EtcdV2) Watch(ctx context.Context, path string, callback WatchCallback) {
	watch := E.Kv.Watcher(path, &client.WatcherOptions{
		Recursive: true,
	})
	for {
		res, err := watch.Next(ctx)
		if err != nil {
			log.Println(err)
			continue
		}
		callback(res.Node.Key, res.Node.Value, res.Action)
		E.SaveMem(ctx, path, res.Node.Value)
	}

}

func (E *EtcdV2) SaveMem(ctx context.Context, path, value string) {
	E.Vp.Set(path, value)
	return
}
